package water_qanxun_api.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.tomcat.util.json.JSONParser;
import org.apache.tomcat.util.json.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import water_qanxun_api.config.MqttConfig;
import water_qanxun_api.controller.util.Code;
import water_qanxun_api.dao.DevicesDao;
import water_qanxun_api.dao.DevicesDataDao;
import water_qanxun_api.domain.DevicesData;
import water_qanxun_api.domain.DevicesDataDomain;
import water_qanxun_api.domain.UserData;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service
public class DevicesDataService {
    @Autowired
    private DevicesDataDao devicesDataDao;
    @Autowired
    private DevicesDao devicesDao;
    
    @Resource
    private MqttConfig mqttConfig;
    
    
    public void isOverThreshold(Map<String, Object> sensor_data, String mac) throws Exception {
        DevicesData devicesData = devicesDao.selectOne(new QueryWrapper<DevicesData>().eq("uid", mac));
        String devConfig = devicesData.getDevConfig();
        // 将json字符串转换为map
        Map<String, Object> configMap = new JSONParser(devConfig).parseObject();
        // 判断是否超过阈值
        if (Integer.parseInt(sensor_data.get("temp").toString()) > Integer.parseInt(configMap.get("temp").toString())) {
            // 发送mqtt消息
            sendMqttMsg(mac, Code.OPEN_FAN);
        }else {
            sendMqttMsg(mac, Code.CLOSE_FAN);
        }
        // 判断light
        if (Integer.parseInt(sensor_data.get("light").toString()) < Integer.parseInt(configMap.get("light").toString())) {
            // 发送mqtt消息
            sendMqttMsg(mac, Code.OPEN_LIGHT);
        }else {
            sendMqttMsg(mac, Code.CLOSE_LIGHT);
        }
        // 判断soilHumi
        if (Integer.parseInt(sensor_data.get("soilHumi").toString()) < Integer.parseInt(configMap.get("soilHumi").toString())&&Integer.parseInt(sensor_data.get("soilHumi").toString())>0) {
            // 发送mqtt消息
            sendMqttMsg(mac, Code.OPEN_WATER_PUMP);
        }
    }
    
    /**
     * 插入设备数据
     * @param uid 用户id
     * @param timestamp 时间戳
     * @param sensor_data 传感器数据
     */
    public void insertData(String uid, Long timestamp,String sensor_data) {
        devicesDataDao.insert(new DevicesDataDomain(timestamp, uid, sensor_data));
    }
    
    /**
     * 发送mqtt消息
     * @param mac 设备mac地址
     * @param msg 消息内容
     */
    public void sendMqttMsg(String mac, String msg) {
        System.out.println("发送mqtt消息: " +"dev/input/"+mac + " " + msg);
        mqttConfig.publish("dev/input/"+mac, msg);
    }
    
    /**
     * 根据mac地址查询设备数据, 并以时间降序排列, 只查询最新的一条数据
     * @param mac 设备mac地址
     * @return 返回设备数据
     */
    public DevicesDataDomain getLatestDeviceDataByMac(String mac) {
        LambdaQueryWrapper<DevicesDataDomain> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(DevicesDataDomain::getDeviceKey, mac)
                .orderByDesc(DevicesDataDomain::getTimestamp)
                .last("limit 1");
        return devicesDataDao.selectOne(queryWrapper);
    }
    
    /**
     * 根据mac地址查询设备数据, 并以时间降序排列, 分页查询
     * @param mac 设备mac地址
     * @param index 页数
     * @return 返回设备数据
     */
    public IPage<DevicesDataDomain> queryDevicesDataByMac(String mac, Integer index) {
        LambdaQueryWrapper<DevicesDataDomain> queryWrapper = new LambdaQueryWrapper<>(); // 创建查询封装类, 并指定数据类
        queryWrapper.orderByDesc(DevicesDataDomain::getTimestamp); // 按照时间降序排列
        queryWrapper.eq(DevicesDataDomain::getDeviceKey, mac);  // 传入账号
        List<DevicesDataDomain> retUserData = devicesDataDao.selectList(queryWrapper); // 查询数据, 并接收返回数据
        if (retUserData.size() == 0) return null; // 如果未查询到数据, 则返回null
        return devicesDataDao.selectPage(new Page<>(index,10), queryWrapper); // 如果查询到数据, 就返回数据
    }
}
